/*
 * Copyright (c) 2015-2018, Marco Frigerio
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include <cmath>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

#include "pronto_quadruped_commons/rbd/rbd.h"


namespace pronto {
namespace robcogen {
namespace test {

/**
 * Read a list of external forces from a text file.
 *
 * Each force is a spatial force, therefore it has six coordinates.
 * The file format is one line for each force vector, each line being a sequence
 * of six numbers, separated by a blank. The file must have as many lines as the
 * number of links of the robot.
 *
 * \param source the input stream to read from
 * \param dest   the container of the external forces that will be filled
 *
 * \tparam Traits the robot traits as generated by RobCoGen
 */
template<class Traits>
void readExtForces(
        std::istream& source,
        typename Traits::FwdDynEngine::ExtForces& dest) // todo use a more generic, do not refer to forward dynamics, although it's the same thing
{
    std::string line;
    std::istringstream in;
    typename Traits::LinkID link;

    for(int i=0; i<Traits::links_count; i++) {
        std::getline(source, line);
        in.str(line);
        in.seekg(std::ios_base::beg);
        for(int f=0; f<6; f++) {
            link = (Traits::orderedLinkIDs())[i];
            in >> (dest[link](f));
        }
    }
}

template<class Traits>
void readExtForces(
        const std::string& extForcesFile,
        typename Traits::FwdDynEngine::ExtForces& fext)
{
    std::ifstream source;
    source.open(extForcesFile.c_str(), std::ios::in);
    if( !source.is_open() ) {
        throw std::runtime_error("Could not open file " + extForcesFile);
    }
    robcogen::test::readExtForces<Traits>(source, fext);
    source.close();
}

}
}
}

#endif
